package com.lazyking.mynetty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;

public class MyWebSocketServer {

    private final int port;

    public MyWebSocketServer(int port) {
        this.port = port;
    }

    public void start() throws Exception {

        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            //http编码解码
                            pipeline.addLast(new HttpServerCodec());
                            //聚合http消息成fullhttprequest
                            pipeline.addLast(new HttpObjectAggregator(65536));
                            //处理静态资源
                            pipeline.addLast(new WebSocketIndexPageHandler("ws"));
                            //握手
                            pipeline.addLast(new WebSocketServerProtocolHandler("/ws", null, true));

                            //压缩
                            pipeline.addLast(new WebSocketServerCompressionHandler());

                            pipeline.addLast(new TestFrameHandler());
                        }
                    });
            //阻塞等待端口绑定完成
            Channel channel = bootstrap.bind(port).sync().channel();
            System.out.println("WebSocket server started at port " + port);
            System.out.println("Open http://localhost:" + port + "/ to test");
            //阻塞等待连接关闭事件，否则一直阻塞(运行中)
            channel.closeFuture().sync();

        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
    public static void main(String[] args) throws Exception {
        new MyWebSocketServer(8080).start();
    }
    static class TestFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
            System.out.println("recived:"+msg.text());
            ctx.writeAndFlush(new TextWebSocketFrame("Server:"+msg.text()));
        }
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            //关闭当前连接 释放资源
            ctx.close();
        }

    }
}
